package packageDataAccess;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.sql.DataSource;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import packageException.*;
import packageModel.Promotion;
import packageModel.Syllabus;

/**
 *
 * @author Lionel & Julien
 */
public class SyllabusSyllathequeData {
    /**
     * Récupère le nombre de syllabus présent dans la base de données
     * 
     * @return nbProduit
     * @throws SyllabusException
     * @throws LangueException
     * @throws AuteurException
     * @throws CategorieException
     * @throws DataException  
     */
    public int getNbProduit() throws 
            SyllabusException, 
            LangueException, 
            AuteurException, 
            CategorieException,
            DataException {
        int syll = 0;
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            // SQL
            String requeteSql = "SELECT COUNT(*) "
                    + "FROM syllabus";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            
            ResultSet donnees = prepStat.executeQuery();
            donnees.next();
            
            syll = donnees.getInt(1);
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new SyllabusException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return syll;
    }

    
    
    /**
     * Récupère toutes les informations correspondant à un syllabus donné
     * 
     * @param syllabusId
     * @return Syllabus
     * @throws SyllabusException
     * @throws LangueException
     * @throws AuteurException
     * @throws CategorieException
     * @throws DataException  
     */
    public Syllabus getProduitSylById(int syllabusId) throws 
            SyllabusException, 
            LangueException, 
            AuteurException, 
            CategorieException,
            DataException {
        Syllabus syll = null;
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            LangueSyllathequeData lsdb = new LangueSyllathequeData();
            CategorieSyllathequeData gcdb = new CategorieSyllathequeData();
            AuteurSyllathequeData asdb = new AuteurSyllathequeData();
            
            // SQL
            String requeteSql = "SELECT s.idSyllabus, s.libelle, s.nbPage, s.prix, s.description, s.langue, s.auteurId, s.categorieId "
                    + "FROM Syllabus as s "
                    + "WHERE idSyllabus = ? ";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setInt(1, syllabusId);
            
            ResultSet donnees = prepStat.executeQuery();
            donnees.next();
            
            syll = new Syllabus(
                        donnees.getInt("idSyllabus"), 
                        donnees.getString("libelle"), 
                        donnees.getInt("nbPage"), 
                        donnees.getDouble("prix"), 
                        donnees.getString("description"), 
                        lsdb.getLangueById(donnees.getInt("langue")), 
                        asdb.getAuteurById(donnees.getInt("auteurId")), 
                        gcdb.getCategorieById(donnees.getInt("categorieId"))
                    );
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new SyllabusException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return syll;
    }
    

    
    /**
     * Récupère toutes les informations correspondant à un syllabus donné
     * 
     * @param syllabusId
     * @return Syllabus
     * @throws SyllabusException
     * @throws DataException  
     */
    public Syllabus getSyllabusById(int syllabusId) throws 
            SyllabusException,
            DataException {
        Syllabus syll = null;
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            // SQL
            String requeteSql = "SELECT s.idSyllabus, s.libelle, s.nbPage, s.prix, "
                    + "s.description, s.langue, s.categorieId "
                    + "FROM Syllabus as s "
                    + "WHERE idSyllabus = ?";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setInt(1, syllabusId);
            
            ResultSet donnees = prepStat.executeQuery();
            donnees.next();
            
            syll = new Syllabus(
                    donnees.getInt("idSyllabus"), 
                    donnees.getString("libelle"), 
                    donnees.getInt("nbPage"), 
                    donnees.getDouble("prix"), 
                    donnees.getString("description")
                  );
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new SyllabusException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return syll;
    }
    

    
    /**
     * Récupère toutes les informations correspondant aux syllabus de la base de données
     * pour la liste des 6 derniers syllabus
     * 
     * @return ArrayList<Syllabus>
     * @throws SyllabusException
     * @throws LangueException
     * @throws AuteurException
     * @throws CategorieException 
     * @throws DataException  
     */
    public ArrayList<Syllabus> getProduitSyl() throws 
            SyllabusException, 
            LangueException,
            AuteurException, 
            CategorieException, 
            DataException {
        ArrayList<Syllabus> syll = new ArrayList<Syllabus>();
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            LangueSyllathequeData lsdb = new LangueSyllathequeData();
            CategorieSyllathequeData gcdb = new CategorieSyllathequeData();
            AuteurSyllathequeData asdb = new AuteurSyllathequeData();
            
            // SQL
            String requeteSql = "SELECT s.idSyllabus, s.libelle, s.nbPage, s.prix, s.description, s.langue, s.categorieId, s.auteurId "
                    + "FROM Syllabus as s "
                    + "ORDER BY idSyllabus "
                    + "DESC";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setMaxRows(6);
            
            ResultSet donnees = prepStat.executeQuery();
            while(donnees.next()) {
               syll.add(new Syllabus(
                           donnees.getInt("idSyllabus"), 
                           donnees.getString("libelle"), 
                           donnees.getInt("nbPage"), 
                           donnees.getDouble("prix"), 
                           donnees.getString("description"), 
                           lsdb.getLangueById(donnees.getInt("langue")), 
                           asdb.getAuteurById(donnees.getInt("auteurId")), 
                           gcdb.getCategorieById(donnees.getInt("categorieId"))
                       ));
            }
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new SyllabusException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return syll;
    }
    


    /**
     * Récupère toutes les informations correspondant aux syllabus de la base de données
     * 
     * @return ArrayList<Syllabus>
     * @throws SyllabusException
     * @throws LangueException
     * @throws AuteurException 
     * @throws CategorieException 
     * @throws DataException  
     */
    public ArrayList<Syllabus> getAllProduitSyl() throws 
            SyllabusException, 
            LangueException,
            AuteurException,
            CategorieException, 
            DataException {
        ArrayList<Syllabus> syll = new ArrayList<Syllabus>();
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            LangueSyllathequeData lsdb = new LangueSyllathequeData();
            CategorieSyllathequeData gcdb = new CategorieSyllathequeData();
            AuteurSyllathequeData asdb = new AuteurSyllathequeData();
            
            // SQL
            String requeteSql = "SELECT s.idSyllabus, s.libelle, s.nbPage, s.prix, s.description, s.langue, s.auteurId, s.categorieId "
                    + "FROM Syllabus as s "
                    + "ORDER BY idSyllabus "
                    + "DESC";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            
            ResultSet donnees = prepStat.executeQuery();
            while(donnees.next()) {
               syll.add(new Syllabus(
                           donnees.getInt("idSyllabus"), 
                           donnees.getString("libelle"), 
                           donnees.getInt("nbPage"), 
                           donnees.getDouble("prix"), 
                           donnees.getString("description"), 
                           lsdb.getLangueById(donnees.getInt("langue")), 
                           asdb.getAuteurById(donnees.getInt("auteurId")), 
                           gcdb.getCategorieById(donnees.getInt("categorieId"))
                       ));
            }
            
            // Fermeture de la connexion
           connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new SyllabusException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return syll;
    }

    
    
    /**
     * Récupère tous les détails d'un syllabus donné !
     * Attention : On vérifie s'il y a des promotions. Si c'est le cas, alors on utilise un constructeur, sinon un autre
     * 
     * @param syllabusId
     * @return Syllabus
     * @throws SyllabusException
     * @throws LangueException
     * @throws AuteurException
     * @throws CategorieException
     * @throws PromotionException
     * @throws MotsClefsException
     * @throws ReductionException
     * @throws DataException  
     */
    public Syllabus getProduitDetailSylById(int syllabusId) throws 
            SyllabusException, 
            LangueException, 
            AuteurException, 
            CategorieException, 
            PromotionException, 
            MotsClefsException, 
            ReductionException,
            DataException {
        Syllabus syll = null;
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            LangueSyllathequeData lsdb = new LangueSyllathequeData();
            CategorieSyllathequeData gcdb = new CategorieSyllathequeData();
            AuteurSyllathequeData asdb = new AuteurSyllathequeData();
            MotsClefsSyllathequeData mcsdb = new MotsClefsSyllathequeData();
            PromotionSyllathequeData psdb = new PromotionSyllathequeData();
            
            // SQL
            String requeteSql = "SELECT s.idSyllabus, s.libelle, s.nbPage, s.prix, s.description, s.langue, s.auteurId, s.categorieId "
                    + "FROM Syllabus as s "
                    + "WHERE idSyllabus = ? ";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setInt(1, syllabusId);
            
            ResultSet donnees = prepStat.executeQuery();
            donnees.next();
            
            Boolean isPromo = null;
            int nbPromo = psdb.getNbPromotionById(donnees.getInt("idSyllabus"));
            int nbMotsClefs = mcsdb.getMotsClefsById(donnees.getInt("idSyllabus")).size();
                    
            // A-t-on une promotion ?
            if(nbPromo == 0) {
                isPromo = false;
            } else {
                // Rechercher la dernière promo en date
                Promotion promo = psdb.getPromotionById(donnees.getInt("idSyllabus"));
                
                if(promo != null) {
                    // Date de fin de la promotion
                    java.util.Date heure = new java.sql.Date(promo.getDateFin().getTimeInMillis());
                    java.util.Date today = new java.util.Date();

                    // La promotion est toujours d'actualité ?
                    if(today.before(heure))
                        isPromo = true;
                    else
                        isPromo = false;
                } else {
                    isPromo = true;
                }
            }
            
            if(isPromo == false) {
                // Création de notre objet qui n'a pas de réduction !!!
                syll = new Syllabus(
                            donnees.getInt("idSyllabus"), 
                            donnees.getString("libelle"), 
                            donnees.getInt("nbPage"), 
                            donnees.getDouble("prix"), 
                            donnees.getString("description"), 
                            lsdb.getLangueById(donnees.getInt("langue")), 
                            asdb.getAuteurById(donnees.getInt("auteurId")), 
                            gcdb.getCategorieById(donnees.getInt("categorieId")),
                            null
                       );
            } else {
                // Création de notre objet qui a une réduction !!!
                syll = new Syllabus(
                            donnees.getInt("idSyllabus"), 
                            donnees.getString("libelle"), 
                            donnees.getInt("nbPage"), 
                            donnees.getDouble("prix"), 
                            donnees.getString("description"), 
                            lsdb.getLangueById(donnees.getInt("langue")), 
                            asdb.getAuteurById(donnees.getInt("auteurId")), 
                            gcdb.getCategorieById(donnees.getInt("categorieId")), 
                            psdb.getPromotionById(donnees.getInt("idSyllabus"))
                        );
            }
            // Création de notre liste de mots-clef
            for(int i = 0; i < nbMotsClefs; i++)
                syll.setMotsClefs(mcsdb.getMotsClefsById(donnees.getInt("idSyllabus")).get(i).toString());
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new SyllabusException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return syll;
    }

    
    
    
    /**
     * Récupère la liste des syllabus correspondant à la catégorie et correspondant au(x) mot(s) recherché
     * 
     * @param syllabus
     * @param categorie
     * @return ArrayList<Syllabus>
     * @throws SyllabusException
     * @throws CategorieException
     * @throws LangueException
     * @throws AuteurException
     * @throws DataException  
     */
    public ArrayList<Syllabus> getSylBySearch(String syllabus, String categorie) throws 
            SyllabusException, 
            CategorieException, 
            LangueException, 
            AuteurException,
            DataException {
        ArrayList<Syllabus> tabSyllabus = new ArrayList<Syllabus>();
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext();
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque");
            Connection connexion = source.getConnection();
            
            CategorieSyllathequeData gcdb = new CategorieSyllathequeData();
            LangueSyllathequeData lsdb = new LangueSyllathequeData();
            AuteurSyllathequeData asdb = new AuteurSyllathequeData();
            
            //SQL
            String requeteSql = "SELECT s.idSyllabus, s.libelle, s.nbPage, s.prix, s.description, "
                    + "s.categorieId, l.langueId, l.denomination, s.auteurId "
                    + "FROM Syllabus as s, Langue as l "
                    + "WHERE (lower(s.libelle) LIKE ? "
                    + "OR lower(s.description) LIKE ? ) "
                    + "AND s.categorieId = ? "
                    + "AND s.langue = l.langueId "
                    + "ORDER BY s.idSyllabus";

            // TRAITEMENT
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setString(1, "%"+syllabus.toLowerCase()+"%");
            prepStat.setString(2, "%"+syllabus.toLowerCase()+"%");
            prepStat.setString(3, categorie);
            
            ResultSet donnees = prepStat.executeQuery();
            
            while(donnees.next()) {
                tabSyllabus.add(new Syllabus(
                                    donnees.getInt("idSyllabus"), 
                                    donnees.getString("libelle"), 
                                    donnees.getInt("nbPage"), 
                                    donnees.getDouble("prix"), 
                                    donnees.getString("description"), 
                                    lsdb.getLangueById(donnees.getInt("langueId")), 
                                    asdb.getAuteurById(donnees.getInt("auteurId")), 
                                    gcdb.getCategorieById(donnees.getInt("categorieId"))
                                ));
            }
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new SyllabusException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return tabSyllabus;
    }
    

    

    /**
     * Récupère la liste des syllabus correspondant au(x) mot(s) recherché dans toutes les catégories
     * 
     * @param syllabus
     * @return ArrayList<Syllabus>
     * @throws SyllabusException
     * @throws CategorieException
     * @throws LangueException
     * @throws AuteurException
     * @throws DataException  
     */
    public ArrayList<Syllabus> getSylBySearch(String syllabus) throws 
            SyllabusException, 
            CategorieException, 
            LangueException, 
            AuteurException,
            DataException {
        ArrayList<Syllabus> tabSyllabus = new ArrayList<Syllabus>();
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext();
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque");
            Connection connexion = source.getConnection();
            
            CategorieSyllathequeData gcdb = new CategorieSyllathequeData();
            LangueSyllathequeData lsdb = new LangueSyllathequeData();
            AuteurSyllathequeData asdb = new AuteurSyllathequeData();
            
            // SQL
            String requeteSql = "SELECT s.idSyllabus, s.libelle, s.nbPage, s.prix, s.description, "
                    + "s.categorieId, l.langueId, l.denomination, s.auteurId "
                    + "FROM Syllabus as s, Langue as l "
                    + "WHERE (lower(s.libelle) LIKE ? "
                    + "OR lower(s.description) LIKE ? ) "
                    + "AND s.langue = l.langueId "
                    + "ORDER BY s.idSyllabus";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setString(1, "%"+syllabus.toLowerCase()+"%");
            prepStat.setString(2, "%"+syllabus.toLowerCase()+"%");
            
            ResultSet donnees = prepStat.executeQuery();
            
            while(donnees.next()) {
                tabSyllabus.add(new Syllabus(
                                    donnees.getInt("idSyllabus"), 
                                    donnees.getString("libelle"), 
                                    donnees.getInt("nbPage"), 
                                    donnees.getDouble("prix"), 
                                    donnees.getString("description"), 
                                    lsdb.getLangueById(donnees.getInt("langueId")), 
                                    asdb.getAuteurById(donnees.getInt("auteurId")), 
                                    gcdb.getCategorieById(donnees.getInt("categorieId"))
                                ));
            }
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new SyllabusException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return tabSyllabus;
    }
    

    
    
    /**
     * Récupère la liste des syllabus correspondant à une catégorie
     * 
     * @param listByCategorie
     * @return ArrayList<Syllabus>
     * @throws SyllabusException
     * @throws CategorieException
     * @throws LangueException
     * @throws AuteurException
     * @throws DataException  
     */
    public ArrayList<Syllabus> getProduitSylByCategorie(int listByCategorie) throws 
            SyllabusException, 
            CategorieException, 
            LangueException, 
            AuteurException,
            DataException {
        ArrayList<Syllabus> syll = new ArrayList<Syllabus>();
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            LangueSyllathequeData lsdb = new LangueSyllathequeData();
            CategorieSyllathequeData gcdb = new CategorieSyllathequeData();
            AuteurSyllathequeData asdb = new AuteurSyllathequeData();
            
            // SQL
            String requeteSql = "SELECT s.idSyllabus, s.libelle, s.nbPage, s.prix, s.description, s.langue, s.auteurId, s.categorieId "
                    + "FROM Syllabus as s "
                    + "WHERE s.categorieId = ? "
                    + "ORDER BY idSyllabus "
                    + "DESC";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setInt(1, listByCategorie);
            
            ResultSet donnees = prepStat.executeQuery();
            
            while(donnees.next()) {
               syll.add(new Syllabus(
                           donnees.getInt("idSyllabus"), 
                           donnees.getString("libelle"), 
                           donnees.getInt("nbPage"), 
                           donnees.getDouble("prix"), 
                           donnees.getString("description"), 
                           lsdb.getLangueById(donnees.getInt("langue")), 
                           asdb.getAuteurById(donnees.getInt("auteurId")), 
                           gcdb.getCategorieById(donnees.getInt("categorieId")))
                       );
            }
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new SyllabusException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        //return syll;
        return syll;
    }
}
